using System;

namespace Solver
{
	internal class BitArray64
	{
		private const byte Base = 64;

		private readonly long length_;
		private readonly Array array_;

        public BitArray64(long length)
			: this(length, false)
		{ }

		public BitArray64(long length, bool defaultValue)
		{
			if (length < 0)
				throw new ArgumentOutOfRangeException("length");

			length_ = length;
			array_ = Array.CreateInstance(typeof(UInt64), (length + Base - 1) / Base);
			if (defaultValue)
			{
				for (long i = 0; i < array_.LongLength; i++)
					array_.SetValue(unchecked((UInt64)(-1)), i);
			}
		}

		public bool this[long index]
		{
			get
			{
				if (index < 0 || index >= length_)
					throw new ArgumentOutOfRangeException("index");
				
				var mask = 1UL << (int)(index % Base);
				var fragment = (UInt64)array_.GetValue(index / Base);
				return (fragment & mask) != 0;
			}
			set
			{
				if (index < 0 || index >= length_)
					throw new ArgumentOutOfRangeException("index");
				
				var mask = 1UL << (int)(index % Base);
				var fragment = (UInt64)array_.GetValue(index / Base);
				if (value)
					fragment |= mask;
				else
					fragment &= ~mask;
				array_.SetValue(fragment, index / Base);
			}
		}
	}
}